package game.breeze.gameserver;

import game.breeze.gameserver.controller.PlayerController;
import game.breeze.message.AppMessage;
import game.breeze.message.Message;
import game.breeze.message.codec.AppMessageCodecFactory;
import game.breeze.socket.connection.MinaConnection;
import game.breeze.socket.connection.NetConnection;
import game.breeze.socket.connection.listener.NetConnectionListener;
import game.breeze.socket.server.MinaNetServer;
import game.breeze.socket.server.listener.NetServerListener;
import game.breeze.socket.util.ByteBuffer;
import game.breeze.socket.util.JobQueueOB;
import game.breeze.socket.util.NetJob;
import game.breeze.socket.util.Utils;
import game.breeze.util.CommonUtils;

import org.apache.log4j.Logger;


public class GameServer implements Runnable, NetConnectionListener, NetServerListener {
	private static final Logger _log = Logger.getLogger(GameServer.class);

	private boolean running;

	private MinaNetServer netServer;

	private long currentWorldTime;

	private long currentBattleTime;

	public GameServer() {

		netServer = new MinaNetServer();

		netServer.setMaxConnections(2000);
		netServer.init(51234, false);
		netServer.addNetServerListener(this);
		netServer.setMessageCodecFactory(new AppMessageCodecFactory());

	}

	public void run() {
		Utils.sleep(10000);
		while (running) {
			Utils.sleep(50);
			long timeMillis = System.currentTimeMillis();
			if (timeMillis - currentWorldTime > 500) {// 500毫秒刷新一次世界
				currentWorldTime = timeMillis;
				// JobQueueOB.getInstance().addJob(Queue.MAIN, new
				// WorldUpdatingJob()); // 给主队列里面加入job
			}
		}
	}

	public void start() {
		if (running)
			return;
		running = true;

		try {
			netServer.start();

			Thread t = new Thread(this, "GameServerNetWork");

			t.setDaemon(true);

			t.start(); // 启动游戏服务器线程

			CommonUtils.printSection("GameServer started");

			// new Thread(new ConsoleInstrunction(),
			// "ConsoleInstrunction").start();
		} catch (Exception ex) {
			_log.error("server running error", ex);
			System.exit(0);
		}
	}

	public void stop() {
		if (!running) {
			return;
		}
		running = false;
		try {
			netServer.stop(); // 停止游戏服务器
			JobQueueOB.getInstance().stop();
		} catch (Exception e) {
		}
	}

	/**
	 * 实始连接
	 */
	public void connectionOpened(NetConnection connection) {
		_log.info("conn open");
		// Tools.println("conn open");
		connection.addListener(this);
		// connection.setTimeout(Queue.GAME_SERVER_TIMEOUT);
		// connection.setPingTime(Queue.GAME_SERVER_PINGTIME);
		// connection.setMaxBufferSize(Queue.GAME_SERVER_MAXBUFFERSIZE);
		// Tools.println("conn opened");

		// 系统时间
		// sendSystemTime(connection);

	}

	/**
	 * 
	 * 连接关闭
	 * 
	 * 
	 */
	public void connectionClosed(NetConnection connection) {

		// if (connection.getAttachment() != null && connection.getAttachment()
		// instanceof HeroController) {
		// HeroController controller = (HeroController)
		// connection.getAttachment();
		// NetJob job = new CloseControllerJob(controller);
		// JobQueueOB.getInstance().addJob(Queue.MAIN, job);
		// }

	}

	/**
	 * 接收数据
	 */
	public void messageArrived(NetConnection conn, Message msg) {

		_log.info("message arrive");

		if (running) {

			AppMessage appMsg = (AppMessage) msg;

			int type = appMsg.getType();

			ByteBuffer buffer = appMsg.getBuffer();

			if (type == AppMessage.MSG_AUTH) {// 登录验证
			} else {

				if (conn.getAttachment() instanceof PlayerController) {

					PlayerController controller = (PlayerController) conn.getAttachment();
//
//					if (controller == null || !controller.isOnline()) {
//						// _log.info("非法操作");
//						return;
//					}
//
//					NetJob job = new ClientMessageJob(type, buffer, (MinaConnection) conn);
//
//					JobQueueOB.getInstance().addJob(Queue.MAIN, job); // 将接收客户端消息的job放到队列中
				}
			}

		}
	}

	/**
	 * 数据分发
	 * 
	 * @param conn
	 * @param appMessage
	 */
	private void processClientMessage(MinaConnection conn, int type, ByteBuffer buffer) {
		// ++++++++++++++++++以下操作中需要conn中持有HeroController+++++++++++++++++++++++++++
		switch (type) {
		case AppMessage.MSG_FIGHT: // 战斗
			break;
		case AppMessage.MSG_SCENE: // 地图内操作
			break;
		case AppMessage.MSG_WORLD:// 世界操作
			break;
		case AppMessage.MSG_CHAT:// 聊天
			break;
		case AppMessage.MSG_SHOP:// 商店
			break;
		case AppMessage.MSG_PLAYER:// 个人操作
			break;
		case AppMessage.MSG_PET:// 宠物操作
			break;
		case AppMessage.MSG_TEAM:// 队伍操作
			break;
		case AppMessage.MSG_TRADE:
			break;
		case AppMessage.MSG_SNS:// 社交组织
			break;
		case AppMessage.MSG_TASK:// 任务
			break;
		case AppMessage.MSG_CAMPAIGN://
			break;
		default:
			break;
		}
	}

	private class WorldUpdatingJob extends NetJob {
		public NetConnection getConn() {
			return null;
		}

		public void run() {
			try {
				// WorldManager.getInstance().update();
			} catch (Exception e) {
				_log.error("world update：", e);
			}
		}

	}

	private class CloseControllerJob extends NetJob {

		// private HeroController controller;
		//
		// public CloseControllerJob(HeroController controller) {
		// this.controller = controller;
		// }

		public NetConnection getConn() {
			return null;
		}

		public void run() {
			try {

				// WorldManager.getInstance().removeHero(controller);

			} catch (Exception e) {
				_log.error("Close HeroController：", e);
			}
		}

	}

	private class BattleUpdatingJob extends NetJob {
		public NetConnection getConn() {
			return null;
		}

		public void run() {
			try {
				// WorldManager.getInstance().updateBattles();

			} catch (Exception e) {
				_log.error("battle update：", e);
			}
		}

	}

	private class ClientMessageJob extends NetJob {

		private int type;
		private ByteBuffer buffer;
		private MinaConnection conn;

		ClientMessageJob(int type, ByteBuffer buffer, MinaConnection conn) {
			this.type = type;
			this.buffer = buffer;
			this.conn = conn;
		}

		public void run() {
			try {
				processClientMessage(conn, type, buffer);
			} catch (Exception e) {
				_log.error("client message：" + type, e);
			}
		}

		public NetConnection getConn() {
			return conn;
		}
	}

}
